package com.cevent.community.app.template.generator;/**
 * Created by Cevent on 2021/9/15.
 */

import com.cevent.community.app.template.utils.DataBaseUtil;
import com.cevent.community.app.template.utils.FieldUtil;
import com.cevent.community.app.template.utils.FreemarkerUtil;
import freemarker.template.TemplateException;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.sql.SQLException;
import java.util.*;

/**
 * @author cevent
 * @description dto、service、controller自动生成器
 * @date 2021/9/15 17:55
 */
public class ControllerApplication {
    private static final Logger LOG= LoggerFactory.getLogger(ControllerApplication.class);
    //生成的模块目标路径节点
    static String PARENT_DIR="com_cevent_communit_app";
    static String MODULE_NAME="business";
    static String COMMON_NAME="common";
    //生成文件目标的路径
    static String targetDtoPath=PARENT_DIR+"\\"+COMMON_NAME+"\\src\\main\\java\\com\\cevent\\community\\app\\"+COMMON_NAME+"\\dto\\";
    static String targetServicePath=PARENT_DIR+"\\"+COMMON_NAME+"\\src\\main\\java\\com\\cevent\\community\\app\\"+COMMON_NAME+"\\service\\";
    static String targetControllerPath=PARENT_DIR+"\\"+MODULE_NAME+"\\src\\main\\java\\com\\cevent\\community\\app\\"+MODULE_NAME+"\\controller\\admin\\";
    //扫描数据库table配置
    static String generatorConfig=PARENT_DIR+"\\"+COMMON_NAME+"\\src\\main\\resources\\generator\\generatorConfig.xml";

    public static void main(String[] args) throws DocumentException, SQLException, IOException, TemplateException {
        //1.1只生成配置文件中第一个table节点
        File file=new File(generatorConfig);
        //1.2读取xml到document文件中
        SAXReader saxReader=new SAXReader();
        Document document=saxReader.read(file);
        //1.3读取xml文件的根节点
        Element rootElement=document.getRootElement();
        //1.4读取context节点
        Element contextElement=rootElement.element("context");
        //1.5定义element作为遍历table对象
        Element tableElement;
        //1.6获取第一个table节点
        tableElement=contextElement.elementIterator("table").next();
        //对应配置文件中的：domainObjectName="Section"
        String Domain=tableElement.attributeValue("domainObjectName");
        //转换小写
        String domain=Domain.substring(0,1).toLowerCase()+Domain.substring(1);
        //表名
        String tableName=tableElement.attributeValue("tableName");
        //获取表注释
        String tableNameCN= DataBaseUtil.getTableComment(tableName);
        LOG.info("freemarker -> controllerGenerator自动生成（dto、service、controller）表名：{}"
                ,tableElement.attributeValue("tableName"));
        LOG.info("大写Domain：{}",tableElement.attributeValue("domainObjectName"));

        //2.获取所有列信息
        List<FieldUtil> fieldUtilList=DataBaseUtil.transferColumnByTableName(tableName);
        //根据fieldUtil类信息，获取所有的set类型集合，typeSet用于ftl中获取java类型集合
        Set<String> typeSet=getJavaTypes(fieldUtilList);
        Map<String,Object> map=new HashMap<>();
        map.put("Domain",Domain);
        map.put("domain",domain);
        map.put("tableNameCN",tableNameCN);
        map.put("module",MODULE_NAME);
        map.put("fieldUtilList",fieldUtilList);
        map.put("typeSet",typeSet);

        //3.service初始化，指定使用的模板名称-->读取
        FreemarkerUtil.initConfig("service.ftl");
        //将map传递到模板,指定生成文件的：路径+文件名-->生成
        FreemarkerUtil.freemarkerGenerator(targetServicePath+Domain+"Service.java",map);
        //4.controller初始化
        FreemarkerUtil.initConfig("controller.ftl");
        FreemarkerUtil.freemarkerGenerator(targetControllerPath+Domain+"Controller.java",map);
        //5.dto初始化
        FreemarkerUtil.initConfig("dto.ftl");
        FreemarkerUtil.freemarkerGenerator(targetDtoPath+Domain+"Dto.java",map);
    }

    /*获取所有的java类型，set去重*/
    public static Set<String> getJavaTypes(List<FieldUtil> fieldUtils){
        Set<String> sets=new HashSet<>();
        for(int i=0;i<fieldUtils.size();i++){
            FieldUtil fieldUtil=fieldUtils.get(i);
            sets.add(fieldUtil.getJavaType());
        }
        return sets;
    }
}
